package bus

import (
	"fmt"
	"github.com/gogf/gf/v2/net/gtcp"
	"github.com/gogf/gf/v2/util/gconv"
	"github.com/simonvetter/modbus"
	"strings"
	"time"
)

type AranMod struct {
	Conf   modbus.ClientConfiguration
	Client *modbus.ModbusClient
}

func New(ip, port string) (*AranMod, error) {
	configuration := modbus.ClientConfiguration{
		URL:     "tcp://" + ip + ":" + port,
		Timeout: 1 * time.Second,
	}
	client, err := modbus.NewClient(&configuration)
	if err != nil {
		return nil, err
	}
	return &AranMod{
		Client: client, Conf: configuration,
	}, nil
}
func (a *AranMod) EditIp(ip, mask, route string) (res string, err error) {
	// 设置服务器地址和端口
	serverAddr := strings.Replace(a.Conf.URL, "tcp://", "", 1)
	splitIp := strings.Split(ip, ".")
	originalByteSlice := []byte{0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x01, 0x10, 0x00, 0x6b, 0x00, 0x07, 0x0e, 0x00, 0x00,
		byte(gconv.Int(splitIp[0])), byte(gconv.Int(splitIp[1])), byte(gconv.Int(splitIp[2])), byte(gconv.Int(splitIp[3])), 0xff, 0xff, 0xff, 0x00,
		byte(gconv.Int(splitIp[0])), byte(gconv.Int(splitIp[1])), byte(gconv.Int(splitIp[2])), 0x01}

	recv, err := gtcp.SendRecv(serverAddr, originalByteSlice, -1)
	for _, i := range originalByteSlice {
		fmt.Printf("%02x ", i)
	}
	fmt.Println()
	for _, i := range recv {
		fmt.Printf("%02x ", i)
	}
	fmt.Println()
	time.Sleep(1 * time.Second)
	originalByteSlic2e := []byte{0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, 0x00, 0x67, 0x00, 0x01}
	sendRecv, err := gtcp.SendRecv(serverAddr, originalByteSlic2e, -1)
	for _, i := range sendRecv {
		fmt.Printf("%02x ", i)
	}
	fmt.Println()
	return "请等待三秒后切段modbus电源并重新连接,使用连接测试检查ip是否变化", nil
}

func (a *AranMod) ReadDI() ([]bool, error) {
	err := a.Client.Open()
	if err != nil {
		return nil, err
	}
	defer a.Client.Close()
	return a.Client.ReadDiscreteInputs(0x10, 6)
}

func (a *AranMod) ReadDO() ([]bool, error) {
	err := a.Client.Open()
	if err != nil {
		return nil, err
	}
	defer a.Client.Close()
	return a.Client.ReadCoils(0x10, 6)
}

func (a *AranMod) WriteDO(i uint16, b bool) error {
	err := a.Client.Open()
	if err != nil {
		return err
	}
	defer a.Client.Close()
	return a.Client.WriteCoil(i, b)
}
